

//constructors should mostly have function calls.  Makes easier to see outline


function nodeConstructorsInit(){
	
	//id counters
	window.highestFruitsId = 0;
	window.highestGoalsId = 0;
	window.highestPremisesId = 0;
	window.highestArgumentsId = 0;
}


function newClaim(loadClaim){
	
	var claim = new Node();
	
	//attach label to claim
		var claimName = document.createElement('div');
		claimName.id = "claimName";
		claimName.innerText = "claim";
		argumentsContainer.appendChild(claimName);
	//end attach label
	
	claim.displayedDiv.id = "A0";
	claim.displayedDiv.className += " argument";
	claim.displayedDiv.className += " claim";
	
	
	claim.DOMParent = argumentsContainer;
	claim.children = [];
	
	//add support button
    claim.displayedDiv.appendChild(newSupportButton(claim));
    claim.supportButton = claim.displayedDiv.supportButton;
    
     //add evidence button
    claim.displayedDiv.appendChild(newEvidenceButton(claim));
    claim.evidenceButton = claim.displayedDiv.evidenceButton;
    
    //add attack button
    claim.displayedDiv.appendChild(newAttackButton(claim));
    claim.attackButton = claim.displayedDiv.attackButton;
	
	//claim.saveAsNew();  //will enable later
	
	//append main div to DOM
	argumentsContainer.appendChild(claim.displayedDiv);
	
	//focus editField so can quickly begin editing
	claim.editField.focus();
	if(loadClaim){
		claim.editField.innerText = loadClaim.contents;
	}
	
	return claim;
}

//constructor for new node
function Node()
{
	
	//used to know when to element gets taller, so child placement can be triggered
	this.oldHeight = 50;
	
    //used to avoid collisions between children and children of other nodes
    this.widthChildren = 220;  //its width is initially the width of itself, since no children 
    this.widthTotal = 220;
    
	//main div
    this.displayedDiv = newDisplayedDiv(this);

	//add close button
	var closeButton = newCloseButton(this);
	this.displayedDiv.appendChild(closeButton);
    this.closeButton = closeButton;

	//add edit field
	var editField = newEditField(this);
    this.displayedDiv.appendChild(editField);
    this.editField = editField;
		    
	//add timestamp, used for determining when to save.
    var timeStamp = newTimeStamp(this);
    this.displayedDiv.appendChild(timeStamp);
    this.lastModified = timeStamp;
    	//update timestamp	
    this.lastModified = new Date().getTime();
    
    //dragging//
	//make "not allowed" cursor appear
	$( this.displayedDiv ).draggable(
			{distance : 4},
			{cursor : 'not-allowed'},
			{helper : 'clone'},
			{opacity : 0.01}
	);
	
	this.assists =[];
	this.children = [];
    
    return this;
}


function newDisplayedDiv(self){
	
	var displayedDiv = document.createElement('div');
	
    displayedDiv.className = 'displayedDiv';
	
	handlers.onMouseUp =  function(event) { return self.onMouseUp(event) };
    	displayedDiv.addEventListener('mouseup', handlers.onMouseUp , false); //to initiate save
    	
    handlers.onDivClick = function(event) { return self.onDivClick(event) };
    	displayedDiv.addEventListener('click', handlers.onDivClick , true);  //to set focus
    
    return displayedDiv;
}

function newEditField(self){
	var editField = document.createElement('div');
	
    editField.className = 'editField';
    editField.setAttribute('contenteditable', true);
    
    handlers.onKeyUp = function() {self.onKeyUp();}
    	editField.addEventListener('keyup', handlers.onKeyUp , false);  //for initiating save soon
    	
    handlers.hotkeys = function () {self.hotkeys(event);}
    	editField.addEventListener('keydown', handlers.hotkeys, false);
    	
	handlers.onBlur = function() {self.onBlur();}
    	editField.addEventListener('blur', handlers.onBlur, false);
    	
    handlers.onFocus = function(event) {self.onFocus(event);}
    	editField.addEventListener('focus', handlers.onFocus, false);
    
    return editField;
}
function newTimeStamp(self){
	var ts = document.createElement('div');
	
    ts.className = 'timestamp';
    
    handlers.onMouseDown = function() { return self.onMouseDown(e) };
    	ts.addEventListener('mousedown', handlers.onMouseDown, false);
    
    return ts;
}

function newFruit(loadFruit){
	
	var fruit = new Node();
	
	fruit.displayedDiv.id = "F" + (highestFruitsId++);
	fruit.displayedDiv.className += " fruit";
	
	fruit.DOMParent = fruitsContainer;
	
	//fruit.saveAsNew();  //will enable later
	
	//append main div to DOM
	fruitsContainer.appendChild(fruit.displayedDiv);

	//focus editField so can quickly begin editing
	fruit.editField.focus();
	
	//if calling during load
	if(loadFruit){
		fruit.editField.innerText = loadFruit.contents;
	}
	
	needExpand("", "fruit");

	
	return fruit;
}

function newGoal(loadGoal){
	
	var goal = new Node();
	
	//The first goal will be special.  It is the goal of this argument, as opposed to the broader goals
																	//of the arguers
	//It will not be closeable and will have a unique color.  This is set in style.css

	
	goal.displayedDiv.id = "G" + (highestGoalsId++);
	goal.displayedDiv.className += " goal";
	
	goal.DOMParent = goalsContainer;
	
	//goal.saveAsNew();  //will enable later
	
	//append main div to DOM
	goalsContainer.appendChild(goal.displayedDiv);

	//focus editField so can quickly begin editing
	goal.editField.focus();
	
	//if calling during load
	if(loadGoal){
		goal.editField.innerText = loadGoal.contents;
	}
	
	needExpand("", "goal");

	
	return goal;
}

function newPremise(loadPremise){
	
	var premise = new Node();
	
	premise.displayedDiv.id = "P" + (highestPremisesId++);
	premise.displayedDiv.className += " premise";
	
	premise.DOMParent = premisesContainer;
	
	//premise.saveAsNew();  //will enable later
	
	//append main div to DOM
	premisesContainer.appendChild(premise.displayedDiv);
	
	//focus editField so can quickly begin editing
	premise.editField.focus();
	if(loadPremise){
		premise.editField.innerText = loadPremise.contents;
	}
	
	needExpand("", "premise");

	return premise;
}

//if it is an assist, it is not a child, it is an assist.  So, each node can be a parent in two different ways.
//**** since assists are different than children, don't need assist target.  That is just the parent.
function newArgument(type, parent, loadObject){
	
	var argument = new Node();
	
	argument.DOMParent = argumentsContainer;
	
	argument.displayedDiv.id = "A" + (++highestArgumentsId);
	argument.displayedDiv.className += " argument";
		//"type" is "support", "attack", "evidence", or "assist"	
	argument.displayedDiv.classList.add(type);    
	
	argument.parent = parent;

	//will be added to end of parent's array of children
	    //don't subtract 1 since parent's array hasn't been updated with this child yet
	    //if, however, it is an assist node, it should be added directly to the right of the creating node
	
	//if not assist, add to normal children
	//if assist, add to assists
	
	if (type !== "assist"){
	    argument.indexToParent = parent.children.length;
	}else{
		argument.indexToParent = parent.assists.length;
	}
    
    argument.children = [];
    argument.assists = [];

	//line for connection to parent
	newLine(argument);
	
    //add support button
    argument.displayedDiv.appendChild(newSupportButton(argument));
    argument.supportButton = argument.displayedDiv.supportButton;
    
     //add evidence button
    argument.displayedDiv.appendChild(newEvidenceButton(argument));
    argument.evidenceButton = argument.displayedDiv.evidenceButton;
    
    //add attack button
    argument.displayedDiv.appendChild(newAttackButton(argument));
    argument.attackButton = argument.displayedDiv.attackButton;
    
    //add assist button
    argument.displayedDiv.appendChild(newAssistButton(argument));
    argument.assistButton = argument.displayedDiv.assistButton;

	//append main div to DOM
	argumentsContainer.appendChild(argument.displayedDiv);
	
	//focus editField so can quickly begin editing
	argument.editField.focus();
	if(loadObject){
		argument.editField.innerText = loadObject.contents;
		argument.changeConnection(loadObject.logicalFallacy);
		argument.changeLabel(loadObject.logicalFallacy);
	}
	
	return argument;

	//not planning to use
    //dragging and dropping//
    
    //Disabling dragging and dropping for now since that functionality doesn't make sense

    /*
    //dragging/////////////////////////////////////

    //these are used for updating children when dragging and for updating children when getting adopted
    	//refers to mouse position when dragging
    	//refers to displayedDiv offset when getting adopted
    argument.oldX = null;
    argument.oldY = null;
    
	$( argument.displayedDiv ).draggable(
		{distance : 5},
		{cursor : 'move'},
		{stack : ".argument"},
		{helper : "clone"},
		{revert : "invalid"},
		{revertDuration : 150},
		{opacity : .5},
		{containment : 'parent'},
		{start : function (event, ui) {
			//set global variable to self (an Object) so that future droppable has access to the object
				//and not just the DOM element
			draggable = argument;
			
			//for calculating how much to move chilren
			argument.oldX = ui.originalPosition.left;
			argument.oldY = ui.originalPosition.top;
			
			//disable dropping for children during drag since that causes problems
			argument.disableChildrenDroppable();
									
			//stop closebutton and makeSupportButton from firing if dragged after a click starts
			$(argument.closeButton).off('click');
			$(argument.supportButton).off('click');
			$(argument.evidenceButton).off('click');
			$(argument.attackButton).off('click');
			
		} },
		{drag: function(event, ui){
			//move children also, if it has any
			if(argument.children){
				//ui.position is offset relative to container.  ui.offset is position relative to screen.
				var changeX = ui.position.left - argument.oldX;
				var changeY = ui.position.top - argument.oldY;
				argument.moveChildren(changeX, changeY);
				
				//the current values become the old values
				argument.oldX = ui.position.left;
				argument.oldY = ui.position.top;
			}
		}},
		{stop: function(event, ui){
			argument.enableChildrenDroppable();
			
			//re-enable listeners for makeSupportButton and closeButton
				//the delay is so they do no fire immediately and trigger the event anyways
				//I have to call the method this way so that the method can identify itself correctly
			setTimeout("draggable.reEnableButtons()",10);
		} }
	); //end jQuery dragging

	//dropping////////////////////////////////
	$(argument.displayedDiv).droppable(
		//"this" represents droppable DOMElement in section below
		
		//can be dropped on by argument class displayedDivs
		{accept : '.argument'},
		//glow when hovered over
		{over : function (event, ui){
			this.classList.add("readyToAccept"); 
		} },
		//stop glowing when no longer hovered over
		{out : function (event, ui){
			this.classList.remove("readyToAccept");
		} },
		{drop : function (event, ui){
			//stop glowing when dropped on
			this.classList.remove("readyToAccept");
			
			droppable = argument;  //so global access to droppable's object
			
			//let draggable's parent know that it is leaving
				if(droppable.parent){
					droppable.parent.relinquishNode(argument);
					droppable.parent = null;
				}
			
			//append dropped object to droppable's object
			argument.adoptNode(draggable);
		} }
	);  //end jQuery dropping
	*/
	
	//argument.saveAsNew();  //will enable later
}




/*
 * make a popup box, a div
 * inside the div there should be a number of options, displayed as a list of text
 * the options: logical connection: if A then B, A therefore B, etc
 * there should also be a separate box with the option to challenge the connection
 * 
 * two boxes: a list of connection types, create challenge to connection
 */



